import { TextNode } from '../package/node/textNode';
import { calculateImagePosition, createImageNode, } from '@/canvasCut/utils/ImgUtil';
import { Debounce, delay } from '@/utils/tool';
import { ImageNode } from '@/canvasCut/package/node/imageNode';
import { BtnNode } from '@/canvasCut/package/node/BtnNode';

export interface CanvasOptions {
  x: number;
  y: number;
  width: number;
  height: number;
  // 背景图片背景
  backgroundPosition: any;
  canvasCut:  any;
  canvasWidth: number;
  canvasHeight: number;
}

export class AiShirtCanvas {
  // 所有对象
  private allNodeObject: Array<TextNode | ImageNode> = [];
  // 当前选中对象
  private selectedNode: TextNode | ImageNode;
  // 画布历史
  private _history: allNodeObject[] = [];
  // 画布
  public _context: CanvasRenderingContext2D;
  private _canvas: HTMLCanvasElement;

  /**
   * 背景色
   */
  public bgColor = 'rgba(242, 90, 39, 0)'

  // 编辑区域位置和大小
  private _canvasOptions: CanvasOptions = {
    x: 0,
    y: 0,
    width: 300,
    height: 500,
    canvasWidth: 300,
    canvasHeight: 500,
  };
  // 删除按钮
  private delBtn;
  // 放大缩小
  private scaleBtn;
  // 旋转按钮
  private rotationBtn;
  // 替换按钮
  private replaceBtn;
  // 编辑按钮
  private editBtn;
  private backgroundPosition;

  private canvasCut;

  private _offScreenCanvas: HTMLCanvasElement;
  private _offScreenCtx: CanvasRenderingContext2D;

  constructor(canvas: any, ctx: any, canvasOptions: CanvasOptions) {
    this._canvas = canvas;
    this._context = ctx;
    this._canvasOptions = canvasOptions;

    this.backgroundPosition = canvasOptions.backgroundPosition;
    this.canvasCut = canvasOptions.canvasCut;
    this.initBtn()

    // 创建离屏元素
    this.getOffScreenCanvas({ width: canvas.width, height: canvas.height });
  }

  /**
   * 创建一个离屏元素
   * @param width
   * @param height
   * @private
   */
  private getOffScreenCanvas({width, height}) {
    // 创建离屏 2D canvas 实例
    const canvas = uni.createOffscreenCanvas({type: '2d', width , height })
    // 获取 context。注意这里必须要与创建时的 type 一致
    const context = canvas.getContext('2d')
    this._offScreenCanvas = canvas;
    this._offScreenCtx = context;
    return context;
  }

  public showController({ x, y, width, height }) {
    this._context.fillStyle = 'transparent';
    this._context.fillRect(x, y, width, height);
    // console.log('showController', x, y, width, height);
  }

  public getImage(imgTempFile: any) {
    return new Promise((resolve, reject) => {
      const image = this._canvas.createImage();
      image.onload = (res) => {
        const { x, y, w, h, scale } = calculateImagePosition(imgTempFile.width, imgTempFile.height, this._canvasOptions.width, this._canvasOptions.height);
        resolve({
          image,
          x,
          y,
          w,
          h,
          scale: 1,
          imageData: imgTempFile.imageData,
        });
      };
      image.src = imgTempFile.imageData;
    });
  }

  public getTextDetail(textStr: string) {}

  /**
   * 添加对象
   * @param node
   */
  addNode(node: TextNode | ImageNode) {
    node.zIndex = this.allNodeObject.length + 2;
    node._context = this._context;
    this.allNodeObject.push(node);
    this.allNodeObject = this.allNodeObject.filter((node) => (node._type === 'text' && node._textStr) || node._type === 'image');
    // .sort((a, b) => a.zIndex - b.zIndex)
  }

  async addDrawControlBtn(selectNodeBox) {
    // console.log('addDrawControlBtn', selectNodeBox);
    if (selectNodeBox) {
      const x = selectNodeBox.x;
      const y = selectNodeBox.y;
      const w = selectNodeBox.width;
      const h = selectNodeBox.height;
      // console.log('x', { x, y, w, h });
      // // // // 删除按钮
      this.delBtn.setSelectNodeBox(selectNodeBox);
      this.delBtn.setXY(-w / 2 - 9, -9 - h / 2);
      this.delBtn.updateShow(true);
      this.delBtn.render(this._offScreenCtx);
      // // 放大缩小
      this.scaleBtn.setSelectNodeBox(selectNodeBox);
      this.scaleBtn.setXY((w - 9) / 2, (-9 + h) / 2);
      this.scaleBtn.updateShow(true);
      this.scaleBtn.render(this._offScreenCtx);
      // // 旋转按钮  (-9 + h) / 2
      this.rotationBtn.setSelectNodeBox(selectNodeBox);
      this.rotationBtn.setXY((w + 4) / 2 + 10, 0);
      this.rotationBtn.updateShow(true);
      this.rotationBtn.render(this._offScreenCtx);

      this.editBtn.updateShow(false);
      this.replaceBtn.updateShow(false);
      if (selectNodeBox._node._type === 'image') {
        // // 替换按钮  (-9 + h) / 2
        this.replaceBtn.setSelectNodeBox(selectNodeBox);
        this.replaceBtn.setXY((w - 9) / 2, -9 - h / 2);
        this.replaceBtn.updateShow(true);
        this.replaceBtn.render(this._offScreenCtx);
      } else if (selectNodeBox._node._type === 'text') {
        // 编辑按钮  (-9 + h) / 2
        this.editBtn.setSelectNodeBox(selectNodeBox);
        this.editBtn.setXY((w - 9) / 2, -9 - h / 2);
        this.editBtn.updateShow(true);
        this.editBtn.render(this._offScreenCtx);
      }
    }
  }

  /**
   * 检测点击位置的元素
   * @param x 点击的x坐标
   * @param y 点击的y坐标
   */
  public getNodeAtPosition(x: number, y: number): any {
    // 判断是否点击再操作按钮商
    for (const node of [this.delBtn, this.scaleBtn, this.rotationBtn, this.replaceBtn, this.editBtn]) {
      console.log('------------', node.show, node)
      if (!node.show) continue;
      if (this.isPointInRotatedRectBtn(x, y, node)) {
        console.log('选中的 操作按钮', node);
        return node;
      }
    }
    // 判断是否点击再 编剧区域外
    const { x: rectX, y: rectY, width: w, height: h } = this._canvasOptions;
    if (!(x >= rectX && x <= rectX + w && y >= rectY && y <= rectY + h)) {
      console.error('判断是否点击再 编剧区域外');
      return null;
    }
    // 判断是否点击在元素内
    for (let i = this.allNodeObject.length - 1; i >= 0; i--) {
      const node = this.allNodeObject[i];
      if (!node.show) continue;
      if (this.isPointInRotatedRect(x, y, node)) {
        return node;
      }
    }
    // for (const node of this.allNodeObject) {
    //
    // }
    return null;
  }

  /**
   * 操作按钮
   * 判断点是否在旋转矩形内
   * @param px 点的x坐标
   * @param py 点的y坐标
   * @param node 节点对象
   */
  private isPointInRotatedRectBtn(px: number, py: number, node: any): boolean {
    if (!this.selectedNode) return;

    const selectNodeBox = node.getSelectNodeBox();

    // 计算点击位置相对于Canvas的坐标
    const x = px;
    const y = py;

    const centerX = selectNodeBox.x + selectNodeBox.width / 2;
    const centerY = selectNodeBox.y + selectNodeBox.height / 2;

    const transformedPoint = this.inverseTransform(x, y, centerX, centerY, (this.selectedNode.rotation * Math.PI) / 180, 1);

    // 3. 检查点是否在按钮内
    const btnX = node.x;
    const btnY = node.y;
    return transformedPoint.x >= btnX && transformedPoint.x <= btnX + node.width && transformedPoint.y >= btnY && transformedPoint.y <= btnY + node.height;
  }

  /**
   * 判断点是否在旋转矩形内
   * @param px 点的x坐标
   * @param py 点的y坐标
   * @param node 节点对象
   */
  private isPointInRotatedRect(px: number, py: number, node: any): boolean {
    // 计算点击位置相对于Canvas的坐标
    const x = px;
    const y = py;

    const centerX = node.x + node.width / 2;
    const centerY = node.y + node.height / 2;

    const transformedPoint = this.inverseTransform(x, y, centerX, centerY, (node.rotation * Math.PI) / 180, node.scale);
    // 2. 检查点是否在原始矩形内
    const halfWidth = node.width / 2;
    const halfHeight = node.height / 2;

    // console.error(
    //     'isPointInRotatedRect ',
    //     [halfWidth, halfWidth, -halfHeight, halfHeight],
    //     transformedPoint,
    // );

    return transformedPoint.x >= -halfWidth && transformedPoint.x <= halfWidth && transformedPoint.y >= -halfHeight && transformedPoint.y <= halfHeight;
  }

  /**
   *
   * @param x
   * @param y
   * @param centerX
   * @param centerY
   * @param angle
   * @param scale
   */
  inverseTransform(x, y, centerX, centerY, angle, scale) {
    // 1. 平移至原点
    const tx = x - centerX;
    const ty = y - centerY;

    // 2. 逆旋转
    const cos = Math.cos(-angle);
    const sin = Math.sin(-angle);
    const rx = tx * cos - ty * sin;
    const ry = tx * sin + ty * cos;

    // 3. 逆缩放
    const sx = rx / scale;
    const sy = ry / scale;
    // console.log('inverseTransform', { x, y, sx, sy });
    return { x: sx, y: sy };
  }

  private rotation = 0;


  // 离屏绘制缓存
  private drawOffScreenCanvas() {
    if (!this._offScreenCtx) return;

    // 清空画布

    this._offScreenCtx.clearRect(0, 0, this._canvas.width, this._canvas.height);

    this.canvasCut.drawModalImg(this.backgroundPosition.img)

    this._drawGrid(this._offScreenCtx);

    this._offScreenCtx.save();
    // 创建裁剪路径
    this._offScreenCtx.beginPath();
    this._offScreenCtx.rect(
      this._canvasOptions.x,
      this._canvasOptions.y,
      this._canvasOptions.width,
      this._canvasOptions.height
    );
    // 应用裁剪
    this._offScreenCtx.clip();
    // // 设置背景色
    this._offScreenCtx.fillStyle = this.bgColor;
    this._offScreenCtx.fillRect(this._canvasOptions.x, this._canvasOptions.y, this._canvasOptions.width, this._canvasOptions.height);


    let selectNode = null;
    // 绘制所有对象
    this.allNodeObject.forEach((objNode) => {
      objNode.render(this._offScreenCtx);

      // 绘制选中边框
      if (objNode.isSelected) {
        selectNode = objNode;
        this.selectedNode = objNode;
      }
    });
    this._offScreenCtx.restore();
    // 选中的节点边框
    if (selectNode) {
      this._offScreenCtx.save();
      const selectNodeBox = {
        x: selectNode._box.x - 2,
        y: selectNode._box.y - 2,
        width: selectNode._box.width + 4,
        height: selectNode._box.height + 4,
        rotation: selectNode.rotation,
        _node: selectNode,
      };

      const centerXY = [selectNodeBox.x + selectNodeBox.width / 2, selectNodeBox.y + selectNodeBox.height / 2];
      this._offScreenCtx.translate(centerXY[0], centerXY[1]);
      this._offScreenCtx.rotate((selectNode.rotation * Math.PI) / 180);
      this._offScreenCtx.strokeStyle = '#F25A27';
      this._offScreenCtx.lineWidth = 1;
      this._offScreenCtx.strokeRect(-selectNodeBox.width / 2, -selectNodeBox.height / 2, selectNodeBox.width, selectNodeBox.height);
      if (!selectNode.isDragging) {
        this.addDrawControlBtn(selectNodeBox);
      }
      this._offScreenCtx.restore();
    }

    // 可编辑区域 节点边框
    this._offScreenCtx.setLineDash([5, 5]); // 设置虚线样式
    this._offScreenCtx.strokeStyle = '#C2C2C2';
    this._offScreenCtx.lineWidth = 2;
    this._offScreenCtx.strokeRect(this._canvasOptions.x - 2, this._canvasOptions.y - 2, this._canvasOptions.width + 4, this._canvasOptions.height + 4);
    this._offScreenCtx.setLineDash([]); // 设置虚线样式
  }

  /**
   * 重绘画布
   */
  public draw = Debounce(async () => {
    if (!this._context) return;

    this._canvas.requestAnimationFrame(() => {

      this.drawOffScreenCanvas();

      const offScreenData = this._offScreenCtx.getImageData(0, 0, this._canvas.width, this._canvas.height);
      this._context.clearRect(0, 0, this._canvas.width, this._canvas.height);
      this._context.drawImage(this._offScreenCanvas, 0, 0, this._canvas.width, this._canvas.height);
      return true;


      // 清空画布
      // this._context.fillStyle = 'red';
      // this._context.fillRect(0, 0, this._canvas.width, this._canvas.height);
      this._context.clearRect(0, 0, this._canvas.width, this._canvas.height);
      // this._offscreenCanvasCtx.clearRect(0, 0, this._offscreenCanvas.width, this._offscreenCanvas.height);

      this.canvasCut.drawModalImg(this.backgroundPosition.img)

      this._drawGrid(this._context);

      this._context.save();
      // 创建裁剪路径
      this._context.beginPath();
      this._context.rect(
        this._canvasOptions.x,
        this._canvasOptions.y,
        this._canvasOptions.width,
        this._canvasOptions.height
      );
      // 应用裁剪
      this._context.clip();
      // // 设置背景色
      this._context.fillStyle = this.bgColor;
      this._context.fillRect(this._canvasOptions.x, this._canvasOptions.y, this._canvasOptions.width, this._canvasOptions.height);


      let selectNode = null;
      // 绘制所有对象
      // console.log('this.allNodeObject', this.allNodeObject, this);
      this.allNodeObject.forEach((objNode) => {
        objNode.render(this._context);

        // 绘制选中边框
        if (objNode.isSelected) {
          selectNode = objNode;
          this.selectedNode = objNode;
        }
      });
      // console.log('this.', this._context);
      // 恢复状态（这样后续的绘制不会受裁剪影响）
      this._context.restore();

      // 选中的节点边框
      if (selectNode) {
        this._context.save();
        const selectNodeBox = {
          x: selectNode._box.x - 2,
          y: selectNode._box.y - 2,
          width: selectNode._box.width + 4,
          height: selectNode._box.height + 4,
          rotation: selectNode.rotation,
          _node: selectNode,
        };

        const centerXY = [selectNodeBox.x + selectNodeBox.width / 2, selectNodeBox.y + selectNodeBox.height / 2];
        this._context.translate(centerXY[0], centerXY[1]);
        this._context.rotate((selectNode.rotation * Math.PI) / 180);
        this._context.strokeStyle = '#0036f9';
        this._context.lineWidth = 1;
        this._context.strokeRect(-selectNodeBox.width / 2, -selectNodeBox.height / 2, selectNodeBox.width, selectNodeBox.height);
        if (!selectNode.isDragging) {
          this.addDrawControlBtn(selectNodeBox);
        }
        this._context.restore();
      }

      // 可编辑区域 节点边框
      this._context.setLineDash([5, 5]); // 设置虚线样式
      this._context.strokeStyle = '#C2C2C2';
      this._context.lineWidth = 2;
      this._context.strokeRect(this._canvasOptions.x - 2, this._canvasOptions.y - 2, this._canvasOptions.width + 4, this._canvasOptions.height + 4);
      this._context.setLineDash([]); // 设置虚线样式
      this._saveToHistory();
    });
  }, 10);

  /**
   * 保存 历史对象
   */
  private _saveToHistory() {
    this._history.push(this.allNodeObject);
  }

  /**
   * 排序 对象
   * @private
   */
  public sortObjectsByZIndex() {
    this.allNodeObject = this.allNodeObject
      .sort((a, b) => a.zIndex - b.zIndex)
      .map((node, index) => {
        node.zIndex = index + 2;
        return node;
      });
  }

  /**
   * 改变节点层级
   * @param node
   * @param type
   */
  public changeNodeZIndex(node, type) {
    const oldIndex = this.allNodeObject.findIndex((item) => item.__id__ === node.__id__);
    if (oldIndex === -1) return;

    // 先从数组中移除该节点
    const currentNode = this.allNodeObject.splice(oldIndex, 1)[0];

    if (type === 'top') {
      // 置于最顶层（数组最后）
      this.allNodeObject.push(currentNode);
    } else if (type === 'bottom') {
      // 置于最底层（数组最前）
      this.allNodeObject.unshift(currentNode);
    } else if (type === 'add') {
      // 向上移动一层（与后一个交换位置）
      const newIndex = Math.min(oldIndex + 1, this.allNodeObject.length);
      this.allNodeObject.splice(newIndex, 0, currentNode);
    } else if (type === 'subtract') {
      // 向下移动一层（与前一个交换位置）
      const newIndex = Math.max(oldIndex - 1, 0);
      this.allNodeObject.splice(newIndex, 0, currentNode);
    }

    // 重新分配 zIndex 值
    this.allNodeObject.forEach((node, index) => {
      node.zIndex = index + 2;
    });
  }

  /**
   * 删除节点
   * @param nodeId
   */
  public delNode(nodeId) {
    this.allNodeObject = this.allNodeObject.filter((item) => item.__id__ !== nodeId);
    // 重新分配 zIndex 值
    this.allNodeObject.forEach((node, index) => {
      node.zIndex = index + 2;
    });
  }

  public nodeSort(newNodeList) {
    this.allNodeObject.forEach((node) => {
      node.zIndex = newNodeList.findIndex((item) => item.id === node.__id__);
    });
    this.sortObjectsByZIndex();
  }

  public clear() {
    this.allNodeObject = [];
    this.selectedNode = null;
   }

  public getCanvas() {
    return this._canvas;
  }
  public getTargetNodeById = (id) => {
    return this.allNodeObject.find((item) => item.__id__ === id);
  };

  private _drawGrid(ctx) {
    // const lineColor = '#E0E0E0';
    // const lineWidth = 1;
    // const gridSize = 20;
    // const width = this._canvas.width;
    // const height = this._canvas.height;
    // // 保存当前上下文状态（样式、变换等）
    // ctx.save();
    //
    // // 设置网格线的样式
    // ctx.strokeStyle = lineColor;
    // ctx.lineWidth = lineWidth;
    //
    // // --- 绘制垂直线 ---
    // ctx.beginPath();
    // // 从 gridSize 开始，每隔 gridSize 画一条线，直到画布右边界
    // for (let x = gridSize; x < width; x += gridSize) {
    //   ctx.moveTo(x, 0); // 移动到起点
    //   ctx.lineTo(x, height); // 画线到终点
    // }
    // ctx.stroke(); // 描边路径
    //
    // // --- 绘制水平线 ---
    // ctx.beginPath();
    // // 从 gridSize 开始，每隔 gridSize 画一条线，直到画布下边界
    // for (let y = gridSize; y < height; y += gridSize) {
    //   ctx.moveTo(0, y); // 移动到起点
    //   ctx.lineTo(width, y); // 画线到终点
    // }
    // ctx.stroke(); // 描边路径
    //
    // // 恢复之前保存的上下文状态
    // ctx.restore();
  }

  private initBtn() {
    createImageNode(this._canvas, 'https://cos.aitshirt.cn/app-icon/%E7%BB%84%202186%402x.png').then((res) => {
      // 删除按钮
      const delBtnImage = new BtnNode({
        x: 0,
        y: 0,
        width: 18,
        height: 18,
        imageData: res.image,
        btnType: 'del',
        zIndex: 9999999,
      });
      this.delBtn = delBtnImage;
    });
    createImageNode(this._canvas, 'https://cos.aitshirt.cn/app-icon/%E7%BB%84%202187%402x.png').then((res) => {
      // 放大缩小
      this.scaleBtn = new BtnNode({
        x: 0,
        y: 0,
        width: 18,
        height: 18,
        imageData: res.image,
        btnType: 'scale',
        zIndex: 9999999,
      });
    });
    createImageNode(this._canvas, 'https://cos.aitshirt.cn/app-icon/%E7%BB%84%202190%402x.png').then((res) => {
      // 旋转按钮
      this.rotationBtn = new BtnNode({
        x: 0,
        y: 0,
        width: 18,
        height: 18,
        imageData: res.image,
        btnType: 'rotate',
        zIndex: 9999999,
      });
    });
    // 替换按钮
    createImageNode(this._canvas, 'https://cos.aitshirt.cn/app-icon/%E7%BB%84%202264.png').then((res) => {
      // 替换按钮
      this.replaceBtn = new BtnNode({
        x: 0,
        y: 0,
        width: 32,
        height: 18,
        imageData: res.image,
        btnType: 'replace',
        zIndex: 9999999,
      });
    });
    // 编辑按钮
    createImageNode(this._canvas, 'https://cos.aitshirt.cn/app-icon/%E7%BB%84%202191.png').then((res) => {
      // 编辑按钮
      this.editBtn = new BtnNode({
        x: 0,
        y: 0,
        width: 32,
        height: 18,
        imageData: res.image,
        btnType: 'edit',
        zIndex: 9999999,
      });
    });
  }

  public toImageData() {
    return this._canvas.toDataURL();
    // const url = this._offScreenCanvas.toDataURL();//('image/webp', 1);
    // console.log('url',  url, this._offScreenCanvas.width, this._canvas.toDataURL(), this._canvas.width)
    // return url;
  }
}
